﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Configuration;
using AMing.Extension.Net40;

namespace MusicForMvc3.Method.Cache
{
    public class CacheHelper
    {
        /// <summary>
        /// 缓存过期时间(分钟)(要是配置异常则默认为5分钟)
        /// </summary>
        public static double CacheOutTime = WebConfigurationManager.AppSettings["CacheOutTime"].To<double>(5);
        /// <summary>
        /// 获取缓存数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetCacheData<T>(string key, HttpContextBase httpContext) where T : class
        {
            try
            {
                object data = httpContext.Cache[key];
                if (data == null)
                {
                    return null;
                }

                return (T)data;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 获取缓存数据，如果没有则调用指定的委托进行数据获取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetCacheData<T>(string key, HttpContextBase httpContext, Func<T> getObj) where T : class
        {
            T temp = GetCacheData<T>(key, httpContext);
            if (temp == null)
            {
                temp = getObj();
                if (temp == null)
                {
                    return null;
                }
                httpContext.Cache.Insert(key, temp, null, DateTime.Now.AddMinutes(CacheOutTime), TimeSpan.Zero);
            }

            return temp;
        }

        /// <summary>
        /// 转换成 特性 类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public static T ToAttribute<T>(object obj, Action<T> callback) where T : class
        {
            T temp = obj as T;
            if (temp != null && callback != null)
            {
                callback(temp);
            }

            return temp;
        }
        /// <summary>
        /// 获取CacheKey
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string GetCacheKey<T>(object data)
        {
            var sb = new StringBuilder();
            var type = typeof(T);
            var propinfos = type.GetProperties();

            sb.AppendFormat("{0}", type.Name);
            foreach (var prop_item in propinfos)
            {
                var attrs = prop_item.GetCustomAttributes(false);
                var val = prop_item.GetValue(data, null) as string;
                foreach (var attr_item in attrs)
                {
                    ToAttribute<CacheKeyAttribute>(attr_item, (attr) =>
                    {
                        if (attr.ValueMD5)
                        {
                            val = val.ToLower();
                            val = AMing.Helper.Net40.MD5Encrypt.Encrypt(val);
                        }
                        sb.AppendFormat("_{0}_{1}", attr.Key ?? prop_item.Name, val);
                    });
                }
            }

            return sb.ToString();
        }


        /// <summary>
        /// 获取只包含apiClass的缓存key
        /// </summary>
        /// <returns></returns>
        public static string GetApiCacheKey<T>(object val)
        {
            Type type = typeof(T);
            PropertyInfo[] pinfos = type.GetProperties();
            StringBuilder sb_key = new StringBuilder();

            sb_key.AppendFormat("{0}", type.Name);


            return sb_key.ToString();
        }

        /// <summary>
        /// 清空所有缓存
        /// </summary>
        public static void ClearAllCache(HttpContextBase httpContext)
        {
            System.Web.Caching.Cache cache = httpContext.Cache;
            System.Collections.IDictionaryEnumerator CacheEnum = cache.GetEnumerator();
            while (CacheEnum.MoveNext())
            {
                string key = CacheEnum.Key.ToString();
                cache.Remove(key);
            }
        }

        /// <summary>
        /// 清空包含指定key的缓存
        /// </summary>
        /// <param name="key"></param>
        public static void ClearCache(string key, HttpContextBase httpContext)
        {
            System.Web.Caching.Cache cache = httpContext.Cache;
            System.Collections.IDictionaryEnumerator CacheEnum = cache.GetEnumerator();
            while (CacheEnum.MoveNext())
            {
                string keyitem = CacheEnum.Key.ToString();
                if (keyitem.Contains(key))
                {
                    cache.Remove(keyitem);
                }
            }
        }
    }
}